/*
JuffEd - A simple text editor
Copyright 2007 Murzin Mikhail

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License 
version 2 as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#include "JuffEd.h"

class JuffEdInterior {
public:
	JuffEdInterior(QMainWindow* parent) : lastCharsetAction_(0), charsetsMenu_(0) {
		handler_ = new DocHandler(parent);
		settingsDlg_ = new SettingsDlg(parent);

		cursorPosL_ = new QLabel("");
		fileNameL_ = new QLabel("");
		charsetL_ = new QLabel("");
		parent->statusBar()->addWidget(cursorPosL_);
		parent->statusBar()->addWidget(fileNameL_);
		parent->statusBar()->addWidget(charsetL_);
	}
	
	~JuffEdInterior () {
		delete handler_;
		delete settingsDlg_;
	}
	
	QMap<QString, QString> icons_;
	DocHandler* handler_;
	SettingsDlg* settingsDlg_;
	QAction* lastCharsetAction_;
	QMenu* charsetsMenu_;

	QLabel* cursorPosL_;
	QLabel* fileNameL_;
	QLabel* charsetL_;
};

JuffEd::JuffEd() {
    
    
	jInt_ = new JuffEdInterior(this);
	//	settings
	QDir localDir(APPCACHEDIR);
	QDir globalDir(QCoreApplication::applicationDirPath());
	QString localPath = localDir.absolutePath();
	QString globalPath = globalDir.absolutePath();
	QString fileName = APPLICATION_SETTING;
	if (!localDir.exists()) {
		localDir.mkpath(localPath);
        /* setup first install */ 
    }
    
    setAcceptDrops(true);
    
    Settings::read("juff", "juffed");
	applySettings();
    
    connect(jInt_->settingsDlg_, SIGNAL(applied()), SLOT(applySettings()));
	createCommands();
	createMenuBar();
	createToolBar();
    loadIcons();
    connect(jInt_->handler_, SIGNAL(statusTextChanged(int, const QString&)), SLOT(setStatusText(int, const QString&)));
    qDebug() << "main wind end ";
}




void JuffEd::OpenFile( QString file ) 
{
    jInt_->handler_->openDoc(file);
}

/*
JuffEd::~JuffEd() {
	MainSettings::setWindowRect(geometry());
	MainSettings::setMaximized(isMaximized());
	Settings::write("juff", "juffed");
}
*/

void JuffEd::SaveXsession() {
    /* call to close and write setting save x11 session qsetting window preference style ecc....*/
    Settings::write("juff", "juffed");
}

void JuffEd::closeEvent(QCloseEvent* e) {
    SaveXsession();
    e->accept();
}

void JuffEd::exit() {
	close();
}

void JuffEd::createCommands() {
	CommandStorage* st = CommandStorage::instance();
	QMap<QString, QString>& icons = jInt_->icons_;
	DocHandler* h = jInt_->handler_;
	Command cmds[] = {
		Command(ID_FILE_NEW,	tr("New"),		QIcon(icons["fileNew"]),	QKeySequence("Ctrl+N"), h, SLOT(newDoc())),
		Command(ID_FILE_OPEN,	tr("Open"),		QIcon(icons["fileOpen"]),	QKeySequence("Ctrl+O"), h, SLOT(openDoc())),
		Command(ID_FILE_SAVE,	tr("Save"),		QIcon(icons["fileSave"]),	QKeySequence("Ctrl+S"), h, SLOT(saveDoc())),
		Command(ID_FILE_SAVE_AS,tr("Save as"),	QIcon(icons["fileSaveAs"]),	QKeySequence(),				h, SLOT(saveDocAs())),
		Command(ID_FILE_CLOSE,	tr("Close"),	QIcon(icons["fileClose"]),	QKeySequence("Ctrl+W"), h, SLOT(closeDoc())),
		Command(ID_FILE_CLOSE_ALL, tr("Close all"), QIcon(icons["fileCloseAll"]), QKeySequence(),	h, SLOT(closeAllDocs())),
		Command(ID_EXIT,		tr("Exit"),		QIcon(icons["exit"]),		QKeySequence(),			this, SLOT(exit())),
		//
		Command(ID_EDIT_CUT,	tr("Cut"),		QIcon(icons["editCut"]),	QKeySequence("Ctrl+X"), h, SLOT(processTheCommand())),
		Command(ID_EDIT_COPY,	tr("Copy"),		QIcon(icons["editCopy"]),	QKeySequence("Ctrl+C"), h, SLOT(processTheCommand())),
		Command(ID_EDIT_PASTE,	tr("Paste"),	QIcon(icons["editPaste"]),	QKeySequence("Ctrl+V"), h, SLOT(processTheCommand())),
		Command(ID_EDIT_UNDO,	tr("Undo"),		QIcon(icons["editUndo"]),	QKeySequence("Ctrl+Z"), h, SLOT(processTheCommand())),
		Command(ID_EDIT_REDO,	tr("Redo"),		QIcon(icons["editRedo"]),	QKeySequence("Ctrl+R"), h, SLOT(processTheCommand())),
		Command(ID_FIND,		tr("Find"),		QIcon(icons["find"]),		QKeySequence("Ctrl+F"), h, SLOT(processTheCommand())),
		Command(ID_FIND_NEXT,	tr("Find next"), QIcon(icons["findNext"]),	QKeySequence("F3"), h, SLOT(processTheCommand())),
		Command(ID_FIND_PREV,	tr("Find previous"), QIcon(icons["findPrev"]), QKeySequence("Shift+F3"), h, SLOT(processTheCommand())),
		Command(ID_GOTO_LINE,	tr("Go to line"), QIcon(icons["gotoLine"]),	QKeySequence("Ctrl+G"), h, SLOT(processTheCommand())),
		//
		Command(ID_DOC_PREV,	tr("Previous"),	QIcon(icons["docPrevious"]),	QKeySequence("Alt+Left"), h, SLOT(processTheCommand())),
		Command(ID_DOC_NEXT,	tr("Next"),		QIcon(icons["docNext"]),	QKeySequence("Alt+Right"), h, SLOT(processTheCommand())),
		//
		Command(ID_SETTINGS,	tr("Settings"),	QIcon(icons["settings"]),	QKeySequence(), this, SLOT(settings())),
		//
		Command(ID_ABOUT,		tr("About"),	QIcon(icons["about"]),		QKeySequence(), this, SLOT(about())),
		Command(ID_ABOUT_QT,	tr("About Qt"),	QIcon(icons["aboutQt"]),	QKeySequence(), this, SLOT(aboutQt())),
		Command()
	};

	for (unsigned i = 0; cmds[i].id != 0; i++) {
		Command& cmd = cmds[i];
		if (st->action(cmd.id) == 0)
			st->registerCommand(cmds[i]);
		else
			st->action(cmd.id)->setIcon(cmd.icon);
	}
}

void JuffEd::createMenuBar() {
	menuBar()->clear();

	CommandID fileMenu[] = { ID_FILE_NEW, ID_FILE_OPEN, ID_FILE_SAVE, ID_FILE_SAVE_AS, ID_SEPARATOR, 
					ID_FILE_CLOSE, ID_FILE_CLOSE_ALL, ID_SEPARATOR, ID_EXIT, ID_NONE };

	CommandID editMenu[] = { ID_EDIT_CUT, ID_EDIT_COPY, ID_EDIT_PASTE, ID_SEPARATOR, ID_EDIT_UNDO, 
					ID_EDIT_REDO, ID_SEPARATOR, ID_FIND, ID_FIND_NEXT, ID_FIND_PREV, 
					ID_SEPARATOR, ID_GOTO_LINE, ID_NONE };

	CommandID docMenu[] = { ID_DOC_PREV, ID_DOC_NEXT, ID_NONE };

	CommandID charsetMenu[] = { ID_NONE };

	CommandID toolsMenu[] = { ID_SETTINGS, ID_NONE };

	CommandID helpMenu[] = { ID_ABOUT, ID_ABOUT_QT, ID_NONE };

	CommandID* menu_ids[] = { fileMenu, editMenu, docMenu, charsetMenu, toolsMenu, helpMenu, 0 };
	char* menus[] = { "File", "Edit", "Document", "Charset", "Tools", "Help", 0 };


	for (unsigned i = 0; menus[i] != 0; i++) {
		QMenu* menu = menuBar()->addMenu(tr(menus[i]));
		if (QString::compare(menus[i], "Charset") == 0)
			jInt_->charsetsMenu_ = menu;

		for (int j = 0; menu_ids[i][j] != ID_NONE; j++) {
			CommandID id = menu_ids[i][j];
			if (id == ID_SEPARATOR)
				menu->addSeparator();
			else {
				QAction* action = CommandStorage::instance()->action(id);
				if (action != 0) {
					menu->addAction(action);
				}
			}
		}
	}

	createCharsetsMenu();

}

void JuffEd::createToolBar() {
	CommandID actions[] = {ID_FILE_NEW, ID_FILE_OPEN, ID_FILE_SAVE, ID_SEPARATOR, 
					ID_EDIT_CUT, ID_EDIT_COPY, ID_EDIT_PASTE, ID_SEPARATOR, 
					ID_EDIT_UNDO, ID_EDIT_REDO, ID_NONE};
	QToolBar* toolBar = addToolBar("Main");
	for (unsigned i = 0; actions[i] != ID_NONE; i++) {
		CommandID id = actions[i];
		if (id == ID_SEPARATOR)
			toolBar->addSeparator();
		else
			toolBar->addAction(CommandStorage::instance()->action(actions[i]));
	}
}

void JuffEd::createCharsetsMenu() {
	if (jInt_->charsetsMenu_ == 0)
		return;

	jInt_->charsetsMenu_->clear();

	QStringList charsets = CharsetsSettings::getCharsetsList();
	foreach (QString charset, charsets) {
		if (CharsetsSettings::charsetEnabled(charset)) {
			QAction* action = jInt_->charsetsMenu_->addAction(charset, this, SLOT(changeCharset()));
			action->setCheckable(true);
		}
	}
}

void JuffEd::changeCharset() {
	QAction* a = qobject_cast<QAction*>(sender());
	if (a != 0) {
		if (jInt_->lastCharsetAction_ != 0)
			jInt_->lastCharsetAction_->setChecked(false);

		if (jInt_->handler_->changeCharset(a->text())) {
			jInt_->lastCharsetAction_ = a;
		}
		else {
			a->setChecked(false);
			if (jInt_->lastCharsetAction_ != 0)
				jInt_->lastCharsetAction_->setChecked(true);
		}
	}
}

void JuffEd::loadIcons() {
	QString iconTheme = MainSettings::iconTheme();
	QDir iconDir(APPCACHEDIR + "icons/" + iconTheme);
	if (!iconDir.exists())
		return;

	QString themeFileName = iconDir.filePath(iconTheme + ".theme");
	QFile file(themeFileName);
	if (file.open(QIODevice::ReadOnly)) {
		QString key, value;
		while (!file.atEnd()) {
			QString line = file.readLine();
			key = line.section('=', 0, 0).simplified();
			value = line.section('=', 1, 1).simplified();
			jInt_->icons_[key] = iconDir.absolutePath() + "/" + value;
		}
		file.close();
	}
}

void JuffEd::settings() {
	jInt_->settingsDlg_->exec();
}

void JuffEd::applySettings() {
	jInt_->handler_->applySettings();
	loadIcons();
	createCommands();
	createCharsetsMenu();
}

void JuffEd::about() {
	QString text = tr("JuffEd is a simple text editor with syntax highlighting\n");
	text += tr("Author: Mikhail Y. Murzin a.k.a. Mezomish");
	QMessageBox::about(this, tr("About"), text);
}

void JuffEd::aboutQt() {
	QMessageBox::aboutQt(this, tr("About Qt"));
}

void JuffEd::setStatusText(int n, const QString& text) {
	switch (n) {
		case 0:
			jInt_->cursorPosL_->setText(text);
			break;
		case 1:
			jInt_->fileNameL_->setText(text);
			break;
		case 2:
			jInt_->charsetL_->setText(text);
			break;
		default: ;
	}
}






void JuffEd::dragEnterEvent(QDragEnterEvent *e)
{
  e->acceptProposedAction();
}



void JuffEd::dropEvent(QDropEvent *e)
{
    
    if(e && e->mimeData()) {
        const QMimeData *data = e->mimeData();
        QStringList urlmixed;
        urlmixed.clear();
        
        QList<QUrl> urlelist;
           if (data->hasUrls()) {
                  urlelist = data->urls(); 
               for ( int i = 0; i < urlelist.size(); ++i ) { 
                   QUrl gettyurl(urlelist.at(i));
                         if (gettyurl.scheme() == "file") {
                             QString localfileupsgo = gettyurl.toLocalFile();
                             if (is_file(localfileupsgo)) {
                             OpenFile(localfileupsgo); 
                             }
                             
                             //////urlmixed.append(localfileupsgo);  
                         }
                   
               }
               
           }
           ////////////qDebug() << "### urlmixed " << urlmixed; 
           /////////QMessageBox::warning(0, tr("Message"),tr("Tot %1 file.").arg(urlmixed.size()));
    }
}






